---
import { fighterGallery } from '@/utils/get-image-count'
import { Icons } from '@/components/Icons'

interface Props {
  id: string
  name: string
}

const { id, name } = Astro.props

const gallery = fighterGallery(id)
const IMAGES_TO_LOAD = Math.min(gallery, 3)
---

<div id="boxer-gallery" class={`grid gap-3 grid-rows-2 grid-cols-2`}>
  {
    Array.from({ length: IMAGES_TO_LOAD }).map((_, index) => {
      const currentIndex = ++index
      const href = `/images/fighters/gallery/${id}/${currentIndex}.webp`

      return (
        <a
          class:list={[
            'boxer-image aspect-square transition hover:scale-105 hover:brightness-110',
            'col-span-1 row-span-1',
            'animate-fade-in animate-delay-[1000ms]',
          ]}
          href={href}
          title={`Abrir imagen ${currentIndex} de la galería de ${name}`}
        >
          <figure class="h-full w-full">
            <picture class="block h-full w-full">
              <img
                loading="lazy"
                decoding="async"
                class="aspect-square h-full w-full rounded object-cover object-top"
                alt={`Imagen de la galería de fotos de ${name}`}
                src={href}
              />
            </picture>
          </figure>
        </a>
      )
    })
  }
  <dialog
    id="lightbox"
    class="mx-auto my-auto h-screen w-full border-none bg-transparent outline-none ring-0 backdrop:bg-black/90 md:mt-20"
  >
    <div
      class="animate-zoom-in mx-auto flex h-[80%] w-[80%] items-center justify-center overflow-hidden"
    >
      <div class="absolute h-full w-full bg-transparent" data-dialog-bg></div>
      <p
        class="font-primary pointer-events-none absolute bottom-0 text-center text-xs text-white/50 md:hidden"
      >
        Desliza para la siguiente
      </p>
      <button
        data-btn-prev
        class="group absolute left-[10px] z-10 hidden cursor-pointer select-none text-transparent transition hover:scale-125 motion-reduce:transition-none motion-reduce:hover:scale-100 md:relative md:left-0 md:flex md:items-center md:justify-center"
        id="btn-prev"
      >
        <Icons.ChevronLeft
          class="stroke-theme-turquoise group-hover:stroke-theme-tickle-me-pink h-20 w-20 bg-transparent fill-transparent"
        />
      </button>
      <div class="z-8 relative h-fit rounded md:h-full">
        <button
          data-btn-close
          id="btn-close"
          type="button"
          class="hover:text-theme-tickle-me-pink text-theme-turquoise absolute right-2 top-2 z-10 hidden cursor-pointer rounded bg-black/60 p-4 transition hover:scale-110 md:block"
        >
          <Icons.XIcon class="h-5 w-5" aria-hidden="true" fill="none" />
        </button>
        <img
          loading="lazy"
          decoding="async"
          class="boxer-gallery-img z-8 h-fit rounded object-contain object-center md:h-full"
          alt={`Imagen de la galería de fotos de ${name}`}
          src={`/images/fighters/gallery/${id}/1.webp`}
        />
      </div>
      <button
        data-btn-next
        class="group absolute right-[10px] z-10 hidden cursor-pointer select-none text-transparent transition hover:scale-125 motion-reduce:transition-none motion-reduce:hover:scale-100 md:relative md:right-0 md:flex md:items-center md:justify-center"
        id="btn-next"
      >
        <Icons.ChevronRight
          class="stroke-theme-turquoise group-hover:stroke-theme-tickle-me-pink h-20 w-20 bg-transparent fill-transparent"
        />
      </button>
    </div>
  </dialog>
</div>

<script>
  import { $ } from '@/lib/dom-selector'

  document.addEventListener('astro:page-load', () => {
    const $lightbox = $('#lightbox') as HTMLDialogElement
    const $gallery = $('#boxer-gallery') as HTMLElement
    const $btnPrev = $('#btn-prev') as HTMLButtonElement
    const $btnNext = $('#btn-next') as HTMLButtonElement
    const $btnClose = $('#btn-close') as HTMLButtonElement
    if (!$gallery) return

    const $links = $gallery?.querySelectorAll('a')

    const updateImg = (link: HTMLElement) => {
      const img = $lightbox?.querySelector('.boxer-gallery-img') as HTMLImageElement
      const newImg = link.querySelector('img') as HTMLImageElement
      if (img && newImg) {
        resetMainImageAnimation(img)
        img.src = newImg.src
        img.classList.add('animate-fade-in')

        img.style.transition = '0.2s ease transform'
        img.style.transform = 'translateX(0)'
      }
    }

    const close = () => {
      $lightbox.close()
      document.body.style.overflow = ''
    }

    $btnClose?.addEventListener('click', close)

    const resetMainImageAnimation = (mainImage: HTMLImageElement) => {
      mainImage.style.animation = 'none'
      mainImage.offsetWidth // trigger reflow
      mainImage.style.animation = ''
    }

    const showPrevImage = () => {
      const current = $gallery.querySelector('a[data-current=true]') as HTMLAnchorElement
      const prev = (current.previousElementSibling ||
        $gallery.querySelector('a:last-of-type')) as HTMLAnchorElement
      prev.click()
    }

    const showNextImage = () => {
      const current = $gallery.querySelector('a[data-current=true]') as HTMLAnchorElement
      const next = (
        current.nextElementSibling?.nodeName === 'A'
          ? current.nextElementSibling
          : $gallery.querySelector('a:first-of-type')
      ) as HTMLAnchorElement
      next.click()
    }

    let isAnimating = false

    const startSwipeDrag = (startEvent: MouseEvent | TouchEvent) => {
      let initialTouchX: number
      let swipeDeltaX: number = 0

      const getTouchX = (e: MouseEvent | TouchEvent) =>
        e instanceof MouseEvent ? e.pageX : e.touches[0].pageX

      const handleSwipeMove = (moveEvent: MouseEvent | TouchEvent) => {
        const currentTouchX = getTouchX(moveEvent)
        swipeDeltaX = currentTouchX - initialTouchX
        const $lightboxImg = $lightbox.querySelector('.boxer-gallery-img') as HTMLImageElement
        if ($lightboxImg) {
          $lightboxImg.style.transform = `translateX(${swipeDeltaX}px)`
        }
      }

      const handleSwipeDecision = () => {
        if (isAnimating) return

        const $lightboxImg = $lightbox.querySelector('.boxer-gallery-img') as HTMLImageElement
        if (!$lightboxImg) return

        if (swipeDeltaX > $lightboxImg.offsetWidth * 0.5) {
          isAnimating = true
          showPrevImage()
        } else if (swipeDeltaX < -$lightboxImg.offsetWidth * 0.5) {
          isAnimating = true
          showNextImage()
        } else {
          $lightboxImg.style.transition = '0.2s ease transform'
          $lightboxImg.style.transform = 'translateX(0)'
        }

        document.removeEventListener('mousemove', handleSwipeMove)
        document.removeEventListener('mouseup', handleSwipeDecision)
        document.removeEventListener('touchmove', handleSwipeMove)
        document.removeEventListener('touchend', handleSwipeDecision)
      }

      initialTouchX = getTouchX(startEvent)

      document.addEventListener('mousemove', handleSwipeMove)
      document.addEventListener('mouseup', handleSwipeDecision)
      document.addEventListener('touchmove', handleSwipeMove, { passive: true })
      document.addEventListener('touchend', handleSwipeDecision, { passive: true })
    }

    const $lightboxImg = $lightbox?.querySelector('.boxer-gallery-img') as HTMLImageElement
    if ($lightboxImg) {
      $lightboxImg.addEventListener('mousedown', (e) => startSwipeDrag(e))
      $lightboxImg.addEventListener('touchstart', (e) => startSwipeDrag(e))
      $lightboxImg.addEventListener('animationend', () => {
        isAnimating = false
      })
    }

    $btnPrev.addEventListener('click', () => {
      if (!$lightbox.open) return
      showPrevImage()
    })

    $btnNext.addEventListener('click', () => {
      if (!$lightbox.open) return
      showNextImage()
    })

    document.addEventListener('keydown', (event) => {
      if (!$lightbox.open) return

      if (event.key === 'Escape') {
        close()
      }

      if (event.key === 'ArrowRight') {
        showNextImage()
      }

      if (event.key === 'ArrowLeft') {
        showPrevImage()
      }
    })

    $lightbox?.addEventListener('click', (event) => {
      const $dialogBg = $('[data-dialog-bg]') as HTMLDivElement
      const canClose = event.target === $dialogBg || event.target === $lightbox
      if (canClose) close()
    })

    // When clicking on a lightbox link
    // use the link image as the main image.
    $links.forEach((link) =>
      link.addEventListener('click', (event) => {
        event.preventDefault()
        // remove current data atribute
        $gallery.querySelector('a[data-current=true]')?.removeAttribute('data-current')
        // set current data atribute
        link.setAttribute('data-current', 'true')

        // update image before show lightbox
        if ($lightbox.open) {
          updateImg(link)
        }

        // add lightbox
        if (!$lightbox.open) {
          updateImg(link)
          $lightbox.showModal()
          document.body.style.overflow = 'hidden'
        }
      }),
    )
  })
</script>
